全局作用域
- 在<script></script>标签里,即为全局作用域。
- 在函数体之外,<script>标签内声明的变量就是全局变量。
-
全局作用域内的变量可以在任何其他的作用域访问和修改。
<script> vara = 0; function func1(){ a = 1; console.log(a); console.log(b); }; func1(); // 1 b is not defined </script> <script> varb = 2; func1(); // 1 2 </script>
局部作用域
- 一个函数体就是一个新的局部作用域。
- 函数内部定义的变量在局部作用域内。
- 函数外部作用域不能访问内部作用域的变量。
-
每个函数有不同的作用域,在其他函数中是不可以访问的(一个函数访问另一个函数变量的时候,通过传递参数)。
<script> function func1(){ var a = 0; }; function func2(){ var b = 2; console.log(b); console.log(a); }; func2(); // 2 a is not defined console.log(b); // b is not defined </script>
作用域链
- 函数作用域里面访问一个变量,先从自身开始找,如果没有,就依次往上一级作用域查找,直到全局作用域,全局作用没有就报错。
-
当我们处于某一个作用域里面,修改某个变量值的时,先修改自身作用域,如果没有就依次修改上一个作用域。
<script> var a = 10; var b = 30; function func(){ var a = 20; // 声明局部变量a a = 2; // 改变局部变量a b = 3; // 本作用域中无b变量,会依次更改上层作用域中的变量 c = 4; // 给未被声明的变量赋值,会泄露带window中 d = 5; // (未报错?)本作用域中无d变量,会依次更改上层作用域中的变量,全部没有则报错 console.log(a); }; console.log(b); // 30 全局变量b // console.log(c); // c is not defined func(); // 2 局部变量a console.log(a); // 10 全局变量a console.log(b); // 3 被下层作用域修改的变量b console.log(c); // 4 被泄露到window中的变量c </script>
delete
-
删除未声明的变量,但是不可以删除已经声明的变量
<script> var a = 10; b = 30; delete a; delete b; console.log(a); // 10 console.log(b); // b is not defined </script>
块作用域(ES6新增)
- let , const 不仅仅是声明变量的区别,它们还有支持块作用域的机制(注意:不是大括号,if,switch,for产生的块)
-
let,consts声明的变量不会泄露到顶层对象,只能声明之后再使用,var可以先赋值,在声明
<script> if(true){ var a = 10; let b = 20; const c = 30; }; console.log(a); // 10 console.log(b); // b is not defined console.log(c); // b is not defined </script>
注意
-
多个作用域问题
<div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <script> var aDiv = document.getElementsByTagName("div"); for(var i = 0; i < 5; i++){ aDiv[i].index = i; // 解决i使用var声明时,在函数作用域中的变量i一直是最后执行结果的问题 aDiv[i].onclick = function(){ console.log(i); // i使用var声明,结果一直都是5, i使用let声明,结果是0 1 2 3 4 // 函数体和for循环不处于同一个作用域,需等前一个作用域执行完,才会执行本作用域 console.log(this.index); // 0 1 2 3 4 } } </script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。